use crate::ast::*;
use crate::error::{CompilerError, Result};
use crate::llvm_backend::LLVMBackend;
use inkwell::values::BasicValueEnum;

impl<'ctx> LLVMBackend<'ctx> {

    /// Generate Result method call
    /// This handles built-in methods for Result<T, E> type
    pub(in crate::llvm_backend) fn generate_result_method_call(
        &mut self,
        method_name: &str,
        result_value: BasicValueEnum<'ctx>,
        result_type: &crate::ast::types::ResultType,
        arguments: &[Expression],
        location: &crate::error::Location,
    ) -> Result<BasicValueEnum<'ctx>> {
        match method_name {
            "is_ok" => self.generate_result_is_ok(result_value),
            "is_err" => self.generate_result_is_err(result_value),
            "unwrap" => self.generate_result_unwrap(result_value, result_type, location),
            "unwrap_err" => self.generate_result_unwrap_err(result_value, result_type, location),
            "expect" => self.generate_result_expect(result_value, result_type, arguments, location),
            "expect_err" => {
                self.generate_result_expect_err(result_value, result_type, arguments, location)
            }
            "unwrap_or" => {
                self.generate_result_unwrap_or(result_value, result_type, arguments, location)
            }
            "unwrap_or_else" => {
                self.generate_result_unwrap_or_else(result_value, result_type, arguments, location)
            }
            "map" => self.generate_result_map(result_value, result_type, arguments, location),
            "map_err" => {
                self.generate_result_map_err(result_value, result_type, arguments, location)
            }
            "map_or" => self.generate_result_map_or(result_value, result_type, arguments, location),
            "map_or_else" => {
                self.generate_result_map_or_else(result_value, result_type, arguments, location)
            }
            "and_then" => {
                self.generate_result_and_then(result_value, result_type, arguments, location)
            }
            "or_else" => {
                self.generate_result_or_else(result_value, result_type, arguments, location)
            }
            "and" => self.generate_result_and(result_value, result_type, arguments, location),
            "or" => self.generate_result_or(result_value, result_type, arguments, location),
            _ => Err(CompilerError::internal(&format!(
                "Unknown Result method: {}",
                method_name
            ))),
        }
    }

}
